#include <head.h>
#include "./wrap.h"
#define PORT (9001)
#define MAX_SZIE (1024)

static void fn(char *p);

int poll_server_main(int argc,char*argv[])
{
    int serversocket = 0;
    int maxi = -1;
    int ret = 0;
    struct sockaddr_in addr, client_addr;
    socklen_t socklen = sizeof(addr);
    struct pollfd pfd[MAX_SZIE];
    memset(&addr, 0, sizeof(addr));
    serversocket = Socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    Bind(serversocket, (struct sockaddr *)&addr, sizeof(addr));
    Listen(serversocket, 10);
    for (size_t i = 0; i < MAX_SZIE; i++)
    {
        pfd[i].fd = -1;
    }
    pfd[0].fd = serversocket,
    pfd[0].events = POLLIN;
    maxi = 0;
    for (;;)
    {
        ret = poll(pfd, maxi + 1, -1);
        if (ret == -1)
        {
            sys_error("poll error");
        }
        else if (ret > 0)
        {
            if (pfd[0].revents & POLLIN)
            {
                int fd = Accept(serversocket, (struct sockaddr *)&client_addr, &socklen);
                char buf[100];
                CLEAR_ARRAY(buf);
                printf("New connection from IP:%s,port:%d\n", inet_ntop(AF_INET, &(client_addr.sin_addr), buf, sizeof(buf)),
                       ntohs(client_addr.sin_port));
                size_t i;
                bool insertFlag = false;
                for (i = 1; i < MAX_SZIE; i++)
                {
                    if (pfd[i].fd == -1)
                    {
                        insertFlag = true;
                        pfd[i].fd = fd;
                        break;
                    }
                }
                pfd[i].events = POLLIN;
                if (i == MAX_SZIE && insertFlag == false)
                {
                    printf("too many clients\n");
                }
                if (maxi < i)
                {
                    maxi = i;
                }
                ret--;
                if (ret == 0)
                {
                    continue;
                }
            }
            if (ret > 0)
            {
                for (size_t i = 1; i < MAX_SZIE && ret; i++)
                {
                    if (pfd[i].fd == -1 || !(pfd[i].revents & POLLIN))
                    {
                        continue;
                    }
                    ret--;
                    char buf[BUFSIZ];
                    CLEAR_ARRAY(buf);
                    size_t len = Read(pfd[i].fd, buf, sizeof(buf));
                    if (len == -1)
                    {
                        if (errno == ECONNRESET)
                        {
                            goto close;
                        }
                    }
                    if (len == 0)
                    {
                    close:
                        Close(pfd[i].fd);
                        pfd[i].fd = -1;
                        printf("client disconnected\n");
                        continue;
                    }
                    fn(buf);
                    Write(pfd[i].fd, buf, len);
                }
            }
        }
    }
}
static void fn(char *p)
{
    if (!p)
    {
        return;
    }
    while (*p)
    {
        *p = toupper(*p);
        p++;
    }
}
static int poll_single_fd(int fd,int event,int timeout)
{
    int ret = 0;
    struct pollfd pfd[2];
    pfd[0].fd = fd;
    pfd[0].events = event;
    pfd[1].fd =-1;
    pfd[1].events = event;
    ret = poll(pfd, 1, timeout);
    if (ret == -1)
    {
        // sys_error("poll error");
        printf("poll err:%s\n",strerror(errno));
        return -1;
    }
    else if (ret > 0)
    {
        if (pfd[0].revents & event)
        {
            return 0;
        }
    }
    return -1;
}
int poll_single_test(void)
{
    int serversocket = 0;
    int maxi = -1;
    int ret = 0;
    struct sockaddr_in addr, client_addr;
    socklen_t socklen = sizeof(addr);
  
    memset(&addr, 0, sizeof(addr));
    serversocket = Socket(AF_INET, SOCK_STREAM, 0);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    Bind(serversocket, (struct sockaddr *)&addr, sizeof(addr));
    Listen(serversocket, 10);


    char buf[BUFSIZ];
    while(1)
    {
        printf("prepare to accept clients...\n");
        int fd = Accept(serversocket, (struct sockaddr *)&client_addr, &socklen);
        while(1){
            if(fd>=0){
                if(0 == poll_single_fd(fd,POLLIN,-1)){
                    ssize_t readlen= read(fd,buf,sizeof(buf)-1);
                    
                    if(readlen>0){
                        buf[readlen]=0;
                        printf("r:%d %s",readlen,buf);
                    }else if(readlen==0){
                        printf("r:0!\n");
                        close(fd);
                        // printf("readlen err:%s\n",strerror(errno));
                        break;
                    }else if(readlen< 0){
                        close(fd);
                    
                        printf("readlen err:%s\n",strerror(errno));
                        break;
                    }
                }else{
                    close(fd);
                    break;
                }
            }else{

            }
        }
       
       
    }
    return 0;
}
int main(int argc,char*argv[])
{
    return poll_single_test();
}
